package com.example.demo40multifilterchain.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

/**
 * 配置多个 Spring Security 过滤器链
 *
 * 1.首先，SecurityConfig 不再需要继承自 WebSecurityConfigurerAdapter 了，只是作为一个普通的配置类，加上 @Configuration 注解即可。
 * 2.提供 UserDetailsService 实例，相当于是我们的数据源。
 * 3.创建静态内部类继承 WebSecurityConfigurerAdapter 类，同时用 @Configuration 注解标记静态内部类是一个配置类，配置类里边的代码就和之前的一样了，无需赘述。
 * 4.每一个静态内部类相当于就是一个过滤器链的配置。
 * 5.注意在静态内部类里边，我没有使用 http.authorizeRequests() 开始，http.authorizeRequests() 配置表示该过滤器链过滤的路径是 /**。在静态内部类里边，我是用了 http.antMatcher("/bar/**") 开启配置，表示将当前过滤器链的拦截范围限定在 /bar/**。
 * 6.当存在多个过滤器链的时候，必然会有一个优先级的问题，所以每一个过滤器链的配置类上通过 @Order(2) 注解来标记优先级。
 */
@Configuration
public class SecurityConfig {

    @Bean
    PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    @Bean
    public UserDetailsService userDetailsService(){
        InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
        inMemoryUserDetailsManager.createUser(User.withUsername("wangnian").password("123").roles("admin").build());
        inMemoryUserDetailsManager.createUser(User.withUsername("zhangsan").password("123").roles("user").build());
        return inMemoryUserDetailsManager;
    }

    @Configuration
    @Order(1)
    public static class DefaultWebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/foo/**").authorizeRequests()
                    .anyRequest().hasRole("admin")
                    .and().formLogin()
                    .permitAll()
                    .and().csrf().disable();
        }
    }

    @Configuration
    @Order(2)
    public static class DefaultWebSecurityConfig2 extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .antMatcher("/bar/**").authorizeRequests()
                    .anyRequest().hasRole("user")
                    .and().formLogin()
                    .permitAll()
                    .and().csrf().disable();
        }
    }

    @Configuration
    @Order(3)
    public static class DefaultWebSecurityConfig3 extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .authorizeRequests()
                    .anyRequest().authenticated()
                    .and().formLogin()
                    .permitAll()
                    .and().csrf().disable();
        }
    }




}
